ENEE350-Spring 2003

Lecture 5

(February 13, 2003)

 

HANDS-ON WITH VESP- SUM EXAMPLE

High Level Representation

int x,y[6],i;

y[0] = 15;

y[1] = 23;

y[2] = -14;

y[3] = 7;

y[4] = 126;

y[5] = 89;

x = y[0];

for(i=1;i< 6;i++)

{ x = x + y[i];}

 

 

Summing numbers in Vesp-1st Draft
Summing numbers in Vesp-Final Version

2007 //Address: 2C Load mov instruction
3001 //Address: 2D
2009 //Address: 2E Load jmp instruction
4056 //Address: 2F
2020 //Address: 30 Load numbers
000F //Address: 31 
2021 //Address: 32 
0017 //Address: 33 
2022 //Address: 34 
00F9 //Address: 35 
2023 //Address: 36 
0007 //Address: 37 
2024 //Address: 38 
007D //Address: 39 
2025 //Address: 3A 
0059 //Address: 3B End load numbers
2002 //Address: 3C Initialize loop-count to 6
0006 //Address: 3D
2008 //Address: 3E Initialize index to 20
0020 //Address: 3F
3000 //Address: 40 Move operand to Register-A
0020 //Address: 41
300A //Address: 42 Save sum
0000 //Address: 43
3000 //Address: 44 Move loop count 
0002 //Address: 45
2001 //Address: 46 Load -1 into Register-B
FFFF //Address: 47
0000 //Address: 48 Add
3002 //Address: 49 Save loop counter
0000 //Address: 4A
5058 //Address: 4B Jump to Halt if loop-count = 0
3000 //Address: 4C Move index to Register-A
0008 //Address: 4D
2001 //Address: 4E Load 1 into Register-B
0001 //Address: 4F
0000 //Address: 50 Increment index by 1
3008 //Address: 51 Save index
0000 //Address: 52
3000 //Address: 53 Move sum into Register-A
000A //Address: 54
4007 //Address: 55 Jump to location 7
0000 //Address: 56 Add
4042 //Address: 57 Jump back to save sum 
7000 //Address: 58 Halt

/*****************************************************************************/

/* VESP COMPUTER *

/* Author: A. Yavuz Oruc *

/* Copyright © 2000. Sabatech Corporation. All rights reserved. *

/*Copying and compiling this program for personal use is permitted. However, *

/*no part of this program may be reproduced or distributed in any form or *

/*by any means, or stored in a database or retrieval system, without the *

/*prior written permission of Sabatech Corporation. (www.sabatech.com) *

/*****************************************************************************/

/* This computer program simulates the fetch,decode

/* and execute cycles of a hypothetical 16-bit computer,

/* called VESP (_V_Ery _Simple _Processor)

/* Revised to reduce the address field to 12 bits. 2/13/03

/* VESP has the following registers:

/* A: 16 bits (Implicit) It refers to location 0 in VESP'smemory

/* B: 16 bits (Implicit) It refers to location 1 in VESP'smemory

/* MAR: 13 bits IR: 16 bits PC: 13 bits

/* Its instruction repertoire consists of the following instructions:

/* ADD: Add Opcode: 000 ----- A = A+B HexCode: 0

/* CMP: Compl Opcode: 001 ----- A = ~A HexCode: 1

/* LDA: Load Opcode: 010 ----- M[IR[3:15] ] = M[MAR+1] HexCode: 2

/* MOV: Move Opcode: 011 ----- M[IR[3:15] ] = M[M[MAR+1][3:15]] HexCode: 3

/* JMP Jump Opcode: 100 ----- PC = IR[3:15] HexCode: 4

/* JEZ: Jump if 0 Opcode: 101 ----- If (A = 0) PC = IR[3:15] HexCode: 5

/* JPS: Jump if + Opcode: 110 ----- If (A > 0) PC = IR[3:15] HexCode: 6

/* HLT: Hlt Opcode: 111 ----- reset = 1 HexCode: 7

/* Programs are entered and displayed in hex code.

/* Please communicate all your questions and comments to

/* A. Yavuz Oruc, Professor

/* University of Maryland, College Park, MD 20742

/* E-mail: yavuz@eng.umd.edu or yavuz@sabatech.com

/* June 2000

*/

#include <iostream.h>

#include <stdio.h>

#include <limits.h>

 

void initialize(void); int readprogram(void);

void displayprogram(int progend);

void displayregisters(void); void displaymemory(void);

void maincycle(void); void fetch(void);

void decode(void); void execute(void);

 

//AYO: Define the registers of the architecture.

typedef struct

{short MAR,PC,IR,clock;

short MEMORY[8192],S,C,F,Z,reset,add,complement;

} architecture; architecture vesp;

 

int j=1;

 

int main(void)

{int address = 0,i = 0,action = 0, step = 0,progend;

initialize();//AYO: Initialize all the registers.

do {vesp.reset = 0; //AYO: vesp will continue to run unless it is reset.

//AYO: Input program, diplay registers or memory

cout << "Type \n 0 to enter a program\n "

<< "1 to display registers\n 2 to display memory: ";

cin >> action; cout << "\n";

//AYO: Read the program, display it, and execute it.

if(action == 0) {progend = readprogram(); displayprogram(progend);

//AYO: Step through or execute the program.

while(vesp.reset == 0)

{while(step == 0 && vesp.reset == 0)

{cout << "Enter 1 if you wish to step the program, and 0 to execute it : ";

scanf("%d",&step);

if(step == 1) {maincycle(); step = 0; break;}

while(vesp.reset == 0) {maincycle();}

}

}

 

//AYO: Display the number of instructions and clock cycles executed.

cout << "The number of instructions executed = ";

printf("%0d",j-1); cout << "\n";

cout << "The number of clock cycles used = ";

printf("%0d",vesp.clock); cout << "\n\n";

j = 1;

}

if (action == 1) displayregisters();

if (action == 2) displaymemory();

if (action == 3) readprogram();

}

while (1);

}

 

void initialize(void)

{vesp.PC = vesp.MEMORY[0] = vesp.MEMORY[1] = vesp.IR = 0;

vesp.reset = 0; vesp.clock = 0;

}

 

int readprogram(void)

{int address,instruction,progend,action;

char filename[16]; FILE *file;

do{ cout << "Enter your program's starting "

<< "address ( >= 2) as a 3-digit hex number: ";

cin >> hex >> vesp.PC;

} while (vesp.PC < 2);

 

address = vesp.PC;

cout << "Enter 0 to type in your program or 1 to read it from a file: ";

cin >> action;

if(action != 0)

{cout << "Enter the file name: "; cin >> filename;

if( (file = fopen(filename,"r")) != NULL)

{

while (fscanf(file,"%x",&instruction) != EOF && address < 8192 )

{

vesp.MEMORY[address] = instruction; address = address + 1;}

}

fclose(file);

}

else

do {cout << "Enter instruction "

<< address -vesp.PC

<< " using a 4-digit hex number" << "\n";

cout << "Or type -1 to end your program: ";

cin >> hex >> instruction; //AYO: read it in hex.

vesp.MEMORY[address] = instruction;

address = address + 1;

}

while ( ( vesp.MEMORY[address-1] != -1 ) && (address < 8192)); //AYO: -1 marks the end.

if (address >= 8192)

{cout << "Memory overflow,"

<< "Please quit from the file menu and restart me!";

return address-1;}

progend = address - 1; return progend;

}

 

void displayprogram(int progend)

{int i;

cout << "\nHere is your program: \n\n";

for (i = vesp.PC; i<= progend; i++)

{

cout << "Location " << hex << i << ": "; //AYO: display it in hex.

printf("%04X",0x0000FFFF & vesp.MEMORY[i]); cout << "\n";

}

}

void displayregisters(void)

{cout << "A = "; printf("%04X", 0x0000FFFF & vesp.MEMORY[0]); cout << ", ";

cout << "B = "; printf("%04X", 0x0000FFFF & vesp.MEMORY[1]); cout << ", ";

cout << "Z = " << vesp.Z; cout << ", ";

cout << "S = " << vesp.S; cout << ", ";

cout << "C = " << vesp.C; cout << ", ";

cout << "F = " << vesp.F; cout << "\n";

cout << "MAR = "; printf("%03X",vesp.MAR); cout << ", ";

cout << "PC = "; printf("%03X",vesp.PC); cout << ", ";

cout << "IR = "; printf("%04X",vesp.IR); cout << ", ";

cout << "reset = " << vesp.reset << "\n\n";

}

 

void displaymemory(void)

{int location1,location2,i, quotient; char d0,d1,d2,d3;

cout << "Enter the first address: ";

scanf("%3X",&location1);

cout << "Enter the last address: ";

scanf("%3X",&location2);

cout << "\n";

for (i = location1; i <= location2; i++)

{cout << "Location " << i << " : ";

// printf("%4X",(short)vesp.MEMORY[i]); cout << "\n";

// number = d0 + 16x(d1 + 16x(d2 + 16xd3))

d0 = vesp.MEMORY[i] % 16; quotient = vesp.MEMORY[i]/16;

d1 = quotient % 16; quotient = quotient/16;

d2 = quotient % 16; quotient = quotient/16;

d3 = quotient % 16;

cout << hex << (0x0000FFFF & vesp.MEMORY[i]); cout << "\n";

//cout << hex << d3;

//cout << hex << d2;

//cout << hex << d1;

//cout << hex << d0;

 

}

cout << "\n";

}

 

void maincycle(void)

{ cout << "Machine Cycle " << j << ": ";

j = j+1;

//AYO: Fetch Step

cout << "PC = "; printf("%03X",vesp.PC); cout << ", ";

cout << "\nFETCH SUBCYCLE\n";

fetch();

cout << "\nClock cycle = "; printf("%0d",vesp.clock); cout << "\n\n";

//AYO: Decode Step

cout << "DECODE SUBCYCLE\n";

decode();

cout << "Clock cycle = "; printf("%0d",vesp.clock); cout << "\n\n";

//AYO: Execute Step

cout << "EXECUTE SUBCYCLE\n";

vesp.add = vesp.complement = 0;

execute();

cout << "Clock cycle = "; printf("%0d",vesp.clock); cout << "\n\n";

//AYO: Display the registers

cout << "A = "; printf("%04X",0x0000FFFF & vesp.MEMORY[0]); cout << ", ";

cout << "B = "; printf("%04X",0x0000FFFF & vesp.MEMORY[1]); cout << ", ";

cout << "Z = " << vesp.Z << ", ";

cout << "S = " << vesp.S << ", ";

cout << "C = " << vesp.C << ", ";

cout << "F = " << vesp.F << "\n";

cout << "MAR = "; printf("%03X",vesp.MAR); cout << ", ";

cout << "reset = " << vesp.reset << "\n";

cout << "add = " << vesp.add << "\n";

cout << "complement = " << vesp.complement << "\n\n";

if( (vesp.IR >> 12 ) == 2 || (vesp.IR >> 12 ) == 3)

{cout << "Memory["; cout << hex << (vesp.IR & 0x0FFF) << "] = ";

printf("%04X",0x0000FFFF & vesp.MEMORY[vesp.IR & 0x0FFF]); cout << ",\n\n";}

}

 

void fetch(void)

{ //clock cycle 1. Load next instruction's address into MAR.

vesp.MAR = vesp.PC; vesp.clock = vesp.clock +1;

vesp.PC = vesp.PC +1; //Increment PC.

//clock cycle 2. Fetch the next Instruction into IR

cout << "MAR = "; printf("%04X",vesp.MAR); cout << ", ";

vesp.IR = vesp.MEMORY[vesp.MAR]; vesp.clock = vesp.clock +1;

cout << "IR = "; printf("%04X",vesp.IR); cout << ", ";

}

 

void decode(void)

{cout << "The decoded instruction is: ";

switch( vesp.IR >> 12)

{//Add //Complement

case 0: cout << "ADD\n"; break; case 1: cout << "CMP\n"; break;

//Load //Move

case 2: cout << "LDA\n"; break; case 3: cout << "MOV\n"; break;

//Jump //Jump if A = 0

case 4: cout << "JMP\n"; break; case 5: cout << "JEZ\n"; break;

//Jump if A > 0 //Halt

case 6: cout << "JPS\n"; break; case 7: cout << "HLT\n"; break;

}

}

 

 

void execute(void)

{ short temp;

switch(vesp.IR >> 12)

{//clock cycle 3.

//Add

case 0:

temp = vesp.MEMORY[0] + vesp.MEMORY[1]; vesp.clock = vesp.clock +1;

if(vesp.MEMORY[0] > 0 && vesp.MEMORY[1] > 0 && temp < 0 ||

vesp.MEMORY[0] < 0 && vesp.MEMORY[1] < 0 && temp >= 0)

vesp.F = 1; else vesp.F = 0; //AYO: Set Overflow Flag

if (vesp.MEMORY[0] < 0 && vesp.MEMORY[1] < 0 || temp > 0 &&

(vesp.MEMORY[0] < 0 && vesp.MEMORY[1] > 0 || vesp.MEMORY[0] > 0 && vesp.MEMORY[1] < 0))

vesp.C = 1; else vesp.C = 0; //AYO: Set Carry Flag

vesp.MEMORY[0] = temp; //Save the sum in MEMORY[0]

//AYO: Set Zero Flag

if(vesp.MEMORY[0] == 0) vesp.Z = 1; else vesp.Z = 0;

//AYO: Set Sign Flag

vesp.S = (vesp.MEMORY[0] & 0x8000 ) >> 15; vesp.add = 1; break;

//Complement

case 1: vesp.MEMORY[0] = ~vesp.MEMORY[0];

vesp.clock = vesp.clock +1;

if(vesp.MEMORY[0] == 0) vesp.Z = 1; else vesp.Z = 0;

vesp.S = (vesp.MEMORY[0] & 0x8000 ) >> 15;

vesp.complement = 1; break;

//Load

case 2: vesp.MEMORY[vesp.IR&0x0FFF] =

vesp.MEMORY[(vesp.MAR) + 1];

vesp.clock = vesp.clock +1; vesp.PC = vesp.PC + 1; break;

//Move

case 3: vesp.MEMORY[vesp.IR&0x0FFF] =

vesp.MEMORY[vesp.MEMORY[(vesp.MAR) + 1]];

vesp.clock = vesp.clock + 2; vesp.PC = vesp.PC + 1; break;

//Jump

case 4: vesp.PC = vesp.IR & 0x1FFF;vesp.clock = vesp.clock +1; break;

//Branch if A is 0

case 5: if (vesp.MEMORY[0] == 0)

{vesp.PC = vesp.IR & 0x0FFF;}

vesp.clock = vesp.clock +1; break;

//Branch if A is > 0

case 6: if (vesp.MEMORY[0] > 0)

{vesp.PC = vesp.IR & 0x0FFF;}

vesp.clock = vesp.clock +1; break;

//Halt

case 7: vesp.reset = 1; vesp.clock = vesp.clock +1; break;

}

}